
#ifndef OPTION_H
#define OPTION_H
#include <map>
/*!
 * \brief types of geometric entities based on VTK nomenclature
 */
enum GEO_TYPE {
  VERTEX = 1,   		/*!< \brief VTK nomenclature for defining a vertex element. */
  LINE = 3,			/*!< \brief VTK nomenclature for defining a line element. */
  TRIANGLE = 5, 		/*!< \brief VTK nomenclature for defining a triangle element. */
  RECTANGLE = 9,		/*!< \brief VTK nomenclature for defining a rectangle element. */
  TETRAHEDRON = 10,     	/*!< \brief VTK nomenclature for defining a tetrahedron element. */
  HEXAHEDRON = 12,      	/*!< \brief VTK nomenclature for defining a hexahedron element. */
  WEDGE = 13,     		/*!< \brief VTK nomenclature for defining a wedge element. */
  PYRAMID = 14  		/*!< \brief VTK nomenclature for defining a pyramid element. */
};


enum SOLVER_TYPE 
{
    GKS_SOLVER = 0
};

/*!
 * \brief types of boundary conditions
 */
enum BC_TYPE {
  EULER_WALL = 1,		/*!< \brief Boundary Euler wall definition. */
  FAR_FIELD = 2,		/*!< \brief Boundary far-field definition. */
  SYMMETRY_PLANE = 3,   	/*!< \brief Boundary symmetry plane definition. */
  INLET_FLOW = 5,		/*!< \brief Boundary inlet flow definition. */
  OUTLET_FLOW = 6,		/*!< \brief Boundary outlet flow definition. */
  PERIODIC_BOUNDARY = 7,	/*!< \brief Periodic boundary definition. */
  NEARFIELD_BOUNDARY = 8,	/*!< \brief Near-Field boundary definition. */
  ELECTRODE_BOUNDARY = 9,	/*!< \brief Electrode boundary definition. */
  DIELEC_BOUNDARY = 10,	/*!< \brief Dipoisson boundary definition. */
  CUSTOM_BOUNDARY = 11,         /*!< \brief custom boundary definition. */
  INTERFACE_BOUNDARY = 12,	/*!< \brief Domain interface boundary definition. */
  DIRICHLET = 13,		/*!< \brief Boundary Euler wall definition. */
  NEUMANN = 14,		/*!< \brief Boundary Neumann definition. */
  DISPLACEMENT_BOUNDARY = 15,		/*!< \brief Boundary displacement definition. */
  LOAD_BOUNDARY = 16,		/*!< \brief Boundary Load definition. */
  FLOWLOAD_BOUNDARY = 17,		/*!< \brief Boundary Load definition. */
  ELEC_DIELEC_BOUNDARY = 22,	/*!< \brief Dipoisson boundary definition for the poissonal potential. */
  ELEC_NEUMANN = 23,		/*!< \brief Boundary Neumann definition. */
  SUPERSONIC_INLET = 24,		/*!< \brief Boundary supersonic inlet definition. */
  NACELLE_INFLOW = 25,		/*!< \brief Boundary nacelle inflow. */
  NACELLE_EXHAUST = 26,		/*!< \brief Boundary nacelle exhaust. */
  ISOTHERMAL = 28,      /*!< \brief No slip isothermal wall boundary condition. */
  HEAT_FLUX  = 29,      /*!< \brief No slip constant heat flux wall boundary condition. */
  PRESSURE_BOUNDARY = 30,   	/*!< \brief Pressure boundary condition. */
  HEAT_FLUX_NONCATALYTIC = 31, /*!< \brief No-slip, constant heat flux, noncatalytic bc. */
  HEAT_FLUX_CATALYTIC= 32, /*!< \brief No-slip, constant heat flux, catalytic bc. */
  ISOTHERMAL_NONCATALYTIC = 33, /*!< \brief No-slip, constant temperature, noncatalytic bc. */
  ISOTHERMAL_CATALYTIC = 34, /*!< \brief No-slip, constant temperature, catalytic bc. */
  ACTDISK_INLET = 35,	/*!< \brief Actuator disk inlet boundary definition. */
  ACTDISK_OUTLET = 36,	/*!< \brief Actuator disk outlet boundary definition. */
  SEND_RECEIVE = 99,		/*!< \brief Boundary send-receive definition. */
  RIEMANN_BOUNDARY= 100   /*!< \brief Riemann Boundary definition. */
};

/*!
 * \class CCreateMap
 * \brief creates a map from a list by overloading operator()
 * \tparam T - the key type in the map
 * \tparam U - the mapped value type in the map
 * \author Boost.Assign and anonymous person on stackoverflow
 *
 * We need this to create static const maps that map strings to enum
 * types.  The implementation is based on the Boost.Assign library.  This
 * particular version is taken from
 * http://stackoverflow.com/questions/138600/initializing-a-static-stdmapint-int-in-c
 */
template <typename T, typename U>
class CCreateMap {
private:
  std::map<T, U> m_map;
public:
  CCreateMap(const T& key, const U& val) {
    m_map[key] = val;
  }
  CCreateMap<T, U>& operator()(const T& key, const U& val) {
    m_map[key] = val;
    return *this;
  }
  operator std::map<T, U>() {
    return m_map;
  }
};
#endif //:~ OPTION_H
